/******************************************************************************
 * @file bsp_led_driver.c
 * @brief led bsp driver source file
 *
 * 详细描述：
 * - 功能1：具体描述
 * - 功能2：具体描述
 * - ...
 *
 * @author jiaqi.lou
 * @date 2024-11-25
 * @version v1.0
 *
 * @note 备注信息 (可选)
 * @warning 警告信息 (可选)
******************************************************************************/
/****************************** include **************************************/
#include "bsp_led_driver.h"
/****************************** include **************************************/

/****************************** define  **************************************/

/****************************** define  **************************************/

/****************************** declare **************************************/

/**************************static function ***********************************/
/**
 * @brief control led driver instance
 * @param[in] period_ms cycle time
 * @param[in] times times
 * @param[in] proportion_on_off prot input
 * 
 * @return led_status_t         led driver status
 */
static led_status_t bsp_led_controler(
    bsp_led_driver_t * const  self, /*led driver instance*/
    uint32_t period_ms,           /*cycle time*/
    uint32_t times,               /*times*/
    led_proportion_t proportion_on_off) /*prot input*/
{
    /*********************0. judge resource***************************** */
    if (self == NULL)
    {
#ifdef DEBUG_OUT
        DEBUG_OUT("led driver is null\r\n");
#endif/* end DEBUG OUT*/
        return LED_ERROR_RESOURCES;
    }else if(self->inited != INITED)
    {
#ifdef DEBUG_OUT
        DEBUG_OUT("led driver is not inited\r\n");
#endif/* end DEBUG OUT*/
        return LED_ERROR_RESOURCES;
    }
    /*********************1. judge parameter***************************** */
    if(0 == period_ms || 0 == times || proportion_on_off > PROPORTION_1_1)
    {
#ifdef DEBUG_OUT
        DEBUG_OUT("led driver param is wrong\r\n");
#endif/* end DEBUG OUT*/
        return LED_ERROR_PARAMETER;
    }
    if(((PROPORTION_1_1 == proportion_on_off )&&(period_ms % 2 != 0)) ||
        ((PROPORTION_1_2 == proportion_on_off )&&(period_ms % 3 != 0))||
        ((PROPORTION_1_3 == proportion_on_off )&&(period_ms % 4 != 0))){
#ifdef DEBUG_OUT
        DEBUG_OUT("led driver protortion and period can't divide to integer \r\n");
#endif/* end DEBUG OUT*/
        return LED_ERROR_NOMEMORY;
    }
    /********************2. save input********************************** */
    self->blink_period_ms = period_ms;
    self->blink_times = times;
    self->proportion_on_off = proportion_on_off;
    /**********3. save temp,prevent led instance call for next********** */
    uint32_t temp_time_piece = 0;
    switch (self->proportion_on_off)
    {
        case PROPORTION_1_3:
            temp_time_piece = self->blink_period_ms / 4;
            break;
        case PROPORTION_1_2:
            temp_time_piece = self->blink_period_ms / 3;
            break;
        case PROPORTION_1_1:
            temp_time_piece = self->blink_period_ms / 2;
            break;
        default:
            break;
    }
    uint32_t temp_period = self->blink_period_ms;
    uint32_t temp_times = self->blink_times;
    /*********************4. led blink********************************** */
    for(uint32_t i = 0; i < temp_times; i++)/*times*/
    {
        self->p_led_operation->pf_led_on();
        self->p_led_os_delay->pf_led_os_delay(temp_time_piece);
        self->p_led_operation->pf_led_off();
        self->p_led_os_delay->pf_led_os_delay(temp_period - temp_time_piece);

    }
    return LED_OK;


}



/**************************public function ***********************************/
/**
 * @brief led driver instance init
 * @param[in] self led driver instance
 * @param[in] p_led_operation led on/off function pointer   
 * @param[in] p_led_timebase led timebase function pointer
 * @param[in] p_led_os_delay os delay function pointer
 */
led_status_t bsp_led_instance(
    bsp_led_driver_t * const self, /*led driver instance*/
    led_operation_t *const p_led_operation, /*led operation function pointer*/
    led_timebase_t *const p_led_timebase,   /*led timebase function pointer*/
#ifdef OS_SUPPORT
    led_os_delay_t *p_led_os_delay /*os delay function pointer*/
#endif                              /* end of os_support*/
    )
{
    /*********************0. judge resource***************************** */
    if (NULL == self || NULL == p_led_operation || NULL== p_led_timebase)
    {
#ifdef DEBUG_OUT
        DEBUG_OUT("null pointer input\r\n");
#endif/* end DEBUG OUT*/
        return LED_ERROR_RESOURCES;
    }
    /*********************1. save input******************************** */
    self->p_led_operation = p_led_operation;
    self->p_led_timebase = p_led_timebase;
#ifdef OS_SUPPORT
    self->p_led_os_delay = p_led_os_delay;
#endif/* end of os_support*/
    self->pf_led_control = bsp_led_controler;
    self->inited = INITED;
    return LED_OK;

}


